package com.sjf.reggie.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sjf.reggie.dto.DishDto;
import com.sjf.reggie.entity.Category;
import com.sjf.reggie.entity.Dish;
import com.sjf.reggie.entity.DishFlavor;
import com.sjf.reggie.mapper.DishFlavorMapper;
import com.sjf.reggie.mapper.DishMapper;
import com.sjf.reggie.service.CategoryService;
import com.sjf.reggie.service.DishFlavorService;
import com.sjf.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author <huangtang>
 * @since 2022/4/26 12:06
 **/
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorService flavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    @Transactional
    public void saveWithFlavor ( DishDto dishDto ) {
        //添加菜品信息
        dishMapper.insert (dishDto);
        //添加口味信息
        List<DishFlavor> flavors = dishDto.getFlavors ();
        flavors = flavors.stream ().map ((item)->{
            item.setDishId (dishDto.getId ());
            return item;
        }).collect (Collectors.toList ());
        flavorService.saveBatch (flavors);
    }

    @Override
    public Page getList ( Integer pageNum , Integer pageSize , String name ) {

        QueryWrapper<Dish> dishDtoQueryWrapper = new QueryWrapper<> ();
        //name不为空则带上那么查询条件
        dishDtoQueryWrapper.lambda ().like (!ObjectUtils.isEmpty (name),Dish::getName,name)
                .orderByDesc (Dish::getUpdateTime);
        Page<Dish> pageInfo = new Page<> (pageNum,pageSize);
        Page<DishDto> dishDtoPage = new Page<> ();
        //执行分页查询
        page (pageInfo , dishDtoQueryWrapper);

        //拷贝对象，忽略rocords对象
        BeanUtils.copyProperties (pageInfo,dishDtoPage,"records");
        List<Dish> records = pageInfo.getRecords ();
        List<DishDto> list = records.stream ().map ((item)->{
            DishDto dishDto = new DishDto ();
            BeanUtils.copyProperties (item,dishDto);
            Long categoryId = item.getCategoryId ();
            Category category = categoryService.getById (categoryId);
            dishDto.setCategoryName (category.getName ());
            return dishDto;
        }).collect (Collectors.toList ());
        dishDtoPage.setRecords (list);
        return dishDtoPage;
    }

    @Override
    public DishDto selectById ( Long id ) {
        DishDto dishDto = new DishDto ();
        //获取dish
        Dish dish = dishMapper.selectById (id);
        //获取flavor
        QueryWrapper<DishFlavor> flavorQueryWrapper = new QueryWrapper<> ();
        flavorQueryWrapper.lambda ().eq (DishFlavor::getDishId,id);
        dishDto.setFlavors (flavorService.list (flavorQueryWrapper));
        BeanUtils.copyProperties (dish,dishDto);
        return dishDto;
    }

    @Override
    @Transactional
    public void edit ( DishDto dishDto ) {
        //修改dish
        updateById (dishDto);
        //修改flavor
        QueryWrapper<DishFlavor> wrapper = new QueryWrapper<> ();
        wrapper.lambda ().eq (DishFlavor::getDishId,dishDto.getId ());
        //先删除
        flavorService.remove (wrapper);
        //再添加
        List<DishFlavor> flavors = dishDto.getFlavors ().stream ().map ((item)->{
            item.setDishId (dishDto.getId ());
            return item;
        }).collect (Collectors.toList ());
        flavorService.saveBatch (flavors);

        Long id = dishDto.getCategoryId ();
        //更新缓存
        String key = "dish_"+id+"_1";
        redisTemplate.delete (key);
    }

    @Override
    public boolean updateStatus ( Integer status , String ids ) {
        UpdateWrapper<Dish> dishUpdateWrapper = new UpdateWrapper<> ();
        boolean result = true;
        //得到id字符串数组
        String[] split = ids.split (",");
        for ( String id : split ) {
            dishUpdateWrapper.lambda ().set (Dish::getStatus,status);
            dishUpdateWrapper.lambda ().eq (Dish::getId,Long.parseLong (id));
            update (dishUpdateWrapper);
            dishUpdateWrapper.clear ();
        }
        return result;
    }

    @Override
    public boolean deleteByIds ( String ids ) {
        String[] split = ids.split (",");
        boolean result = true;
        for ( String id : split ) {
            //先删除菜品
            result ^= removeById (id);
            //再删除菜品对应的口味
            UpdateWrapper<DishFlavor> wrapper = new UpdateWrapper<> ();
            wrapper.lambda ().eq (DishFlavor::getDishId,id);
            result ^= flavorService.remove (wrapper);
        }
        return result;
    }

    @Override
    public List<DishDto> getFoodWithSetmeal ( Long categoryId ,String name,Integer status) {
        List<DishDto> dishDtoList = null;
        String key = "dish_"+categoryId+"_"+status;
        //先从redis中获取数据，如果没有再去查询数据库，查询后放入缓存中
        dishDtoList =( List<DishDto>) redisTemplate.opsForValue ().get (key);
        if(dishDtoList != null){
            //如果存在直接返回缓存数据
            return dishDtoList;
        }
        //否则查询数据库
        //默认通过categoryId获取，可以通过name获取
        QueryWrapper<Dish> wrapper = new QueryWrapper<> ();
        wrapper.lambda ().eq (categoryId!=null,Dish::getCategoryId,categoryId)
                .like (name!=null,Dish::getName,name)
                .orderByAsc (Dish::getSort)
                .orderByDesc (Dish::getUpdateTime)
                .eq (Dish::getStatus,1); //查询起售的菜品
        List<Dish> dishList = list (wrapper);
        dishDtoList = dishList.stream ().map ((item)->{
            DishDto dishDto = new DishDto ();
            BeanUtils.copyProperties (item,dishDto);
            Category category = categoryService.getById (item.getCategoryId ());
            if(category!=null){
                dishDto.setCategoryName (category.getName ());
            }
            QueryWrapper<DishFlavor> queryWrapper = new QueryWrapper<> ();
            queryWrapper.lambda ().eq (DishFlavor::getDishId,item.getId ());
            List<DishFlavor> flavorList = flavorService.list (queryWrapper);
            dishDto.setFlavors (flavorList);
            return dishDto;
        }).collect(Collectors.toList());
        //查询完数据库后，放入缓存中
        //缓存时间60分钟
        redisTemplate.opsForValue ().set (key, dishDtoList, 60, TimeUnit.SECONDS);
        return  dishDtoList;
    }
}
